
#ifndef W25N01GV_DRV_H
#define W25N01GV_DRV_H

#include "main.h"

#define SPI_NAND_CS_CLK_ENABLE()    LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA)
#define SPI_NAND_CS_GROUP           GPIOA
#define SPI_NAND_CS_PIN             LL_GPIO_PIN_4

#define SPI_NAND_CLK_CLK_ENABLE()   LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA)
#define SPI_NAND_CLK_GROUP          GPIOA
#define SPI_NAND_CLK_PIN            LL_GPIO_PIN_5

#define SPI_NAND_MISO_CLK_ENABLE()  LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA)
#define SPI_NAND_MISO_GROUP         GPIOA
#define SPI_NAND_MISO_PIN           LL_GPIO_PIN_6

#define SPI_NAND_MOSI_CLK_ENABLE()  LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA)
#define SPI_NAND_MOSI_GROUP         GPIOA
#define SPI_NAND_MOSI_PIN           LL_GPIO_PIN_7

#define SPI_NAND_WP_CLK_ENABLE()    LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA)
#define SPI_NAND_WP_GROUP           GPIOA
#define SPI_NAND_WP_PIN             LL_GPIO_PIN_2

#define SPI_NAND_HOLD_CLK_ENABLE()  LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA)
#define SPI_NAND_HOLD_GROUP         GPIOA
#define SPI_NAND_HOLD_PIN           LL_GPIO_PIN_3

#define SPI_NAND_SPI_CLK_ENABLE()   LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1)
#define SPI_NAND_SPI                SPI1

#define SOFT_SPI_RW_BIT(RW, BIT) (RW << 1 | BIT) /* RW is 0 for read, 1 for write */
#define SOFT_SPI_CS_LOW_DELAY_US 2

#include <w25n01gvzeig.h>

enum w25n01gv_spi_mode
{
    normal_4line,
    normal_3line,
    dual_tx,
    dual_rx,
    quad_tx,
    quad_rx
};

/// @brief
/// @param tx_buf
/// @param tx_cnt
/// @return
int board_w25n01gv_spi_tx_interface(w25n01gv_uint8_t *tx_buf, w25n01gv_uint16_t tx_cnt, w25n01gv_uint8_t tx_io_struct);

/// @brief
/// @param tx_buf
/// @param tx_cnt
/// @param rx_buf
/// @param rx_cnt
/// @return
int board_w25n01gv_spi_tx_rx_interface(w25n01gv_uint8_t *tx_buf, w25n01gv_uint16_t tx_cnt, w25n01gv_uint8_t *rx_buf, w25n01gv_uint16_t rx_cnt, w25n01gv_uint8_t tx_io_struct, w25n01gv_uint8_t rx_io_struct);

/// @brief
/// @param delay_us
/// @return
int board_w25n01gv_delay_us(w25n01gv_uint16_t delay_us);

/// @brief
/// @param size
/// @return
void *board_w25n01gv_malloc(w25n01gv_uint32_t size);

/// @brief
/// @param pos
void board_w25n01gv_free(void *pos);

/// @brief
/// @param str1
/// @param str2
/// @param n
void board_w25n01gv_memcpy(void *str1, const void *str2, w25n01gv_uint32_t n);

/// @brief w25n01 NAND Flash init
/// @param spi_mode 0 hard spi, 1 soft spi
/// @return
int board_w25n01gv_init();

#endif
